library ieee;
use ieee.std_logic_1164.all;

entity regfile_tb is
end regfile_tb;

architecture behav of regfile_tb is
    component regfile is
        port(
        ra1, ra2, wa3: in std_logic_vector(4 downto 0);
        wd3: in std_logic_vector(31 downto 0);
        clk, we: in std_logic;
        rd1, rd2: out std_logic_vector(31 downto 0)
        );
    end component;

    signal ra1_s, ra2_s, wa3_s: std_logic_vector(4 downto 0);
    signal wd3_s: std_logic_vector(31 downto 0);
    signal clk_s, we_s: std_logic;
    signal rd1_s, rd2_s: std_logic_vector(31 downto 0);

begin
    DM0: regfile port map(ra1_s, ra2_s, wa3_s, wd3_s, clk_s, we_s, rd1_s, rd2_s);

    process -- Clock signal
    begin
        clk_s <= '1';
        wait for 1 ns;
        clk_s <= '0';
        wait for 1 ns;
    end process;

    process -- Some test values
        constant unknown: std_logic_vector(31 downto 0) := (others => 'U');
    begin
        we_s <= '1';
        ra1_s <= "00000";
        ra2_s <= "00000";
        wa3_s <= "00001";
        wd3_s <= x"FFFFAAAA";
        wait for 1 ns;
        assert rd1_s = x"00000000" report "Unexpected rd1 (1)" severity error;
        assert rd2_s = x"00000000" report "Unexpected rd2 (1)" severity error;

        ra1_s <= "00000";
        ra2_s <= "00001";
        wa3_s <= "00001";
        wd3_s <= x"FFFFAAAA";
        wait for 1 ns;
        assert rd1_s = x"00000000" report "Unexpected rd1 (1)" severity error;
        assert rd2_s = x"FFFFAAAA" report "Unexpected rd2 (1)" severity error;

        ra1_s <= "00001";
        ra2_s <= "00000";
        wa3_s <= "00001";
        wd3_s <= x"AAAA0000";
        wait for 2 ns;
        assert rd1_s = x"AAAA0000" report "Unexpected rd1 (2)" severity error;
        assert rd2_s = x"00000000" report "Unexpected rd2 (2)" severity error;

        we_s <= '0';
        ra1_s <= "00000";
        ra2_s <= "00011";
        wa3_s <= "00011";
        wd3_s <= x"0000FFFF";
        wait for 2 ns;
        assert rd1_s = x"00000000" report "Unexpected rd1 (3)" severity error;
        assert rd2_s = unknown report "Unexpected rd2 (3)" severity error;

        we_s <= '1';
        wait for 2 ns;
        assert rd1_s = x"00000000" report "Unexpected rd1 (4)" severity error;
        assert rd2_s = x"0000FFFF" report "Unexpected rd2 (4)" severity error;

        ra1_s <= "00010";
        ra2_s <= "00010";
        wa3_s <= "00010";
        wd3_s <= x"0000FFAA";
        wait for 2 ns;
        assert rd1_s = x"0000FFAA" report "Unexpected rd1 (5)" severity error;
        assert rd2_s = x"0000FFAA" report "Unexpected rd2 (5)" severity error;

        ra1_s <= "00000";
        ra2_s <= "00010";
        wa3_s <= "00000";
        wd3_s <= x"AABBCCDD";
        wait for 2 ns;
        assert rd1_s = x"00000000" report "Unexpected rd1 (6)" severity error;
        assert rd2_s = x"0000FFAA" report "Unexpected rd2 (6)" severity error;

        we_s <= '0';
        wait;
    end process;
end behav;
